package jonaPad;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JMenuBar;
import javax.swing.JFrame;
import javax.swing.KeyStroke;
import javax.swing.JToolBar;
import java.awt.event.*;
import java.awt.*;
import javax.swing.JFileChooser;
import java.io.*;
import java.util.*;

import javax.swing.border.*;

import com.thoughtworks.xstream.XStream;
import javax.swing.*;
import Jona.*;
import jonaVisual.*;
import argModelChecker.*;
import jonaTextGen.*;
import jonaArgumentationSchemes.*;

public class JonaPad extends JFrame  implements ActionListener, ComponentListener, ItemListener, MouseListener{
	static final long  serialVersionUID = 10102;
	JFileChooser jfc1;
	XStream xstream = new XStream();
	JScrollPane theoryPane,problemsPane, jsp3, gentextPaneA, gentextPaneB, suggestionPane, knowledgePane, argModelField;
	JTextArea jta1;
	JTextArea jta2;
	JonaTextArea jonta1;
	JTabbedPane jtp1,jtp2,jtp3;
	ModelJTextArea modelTextField;
	JTextArea gentextA,gentextB;
	JComboBox jcb1;
	VisualJPanel VisualJPanelOne,VisualJPanelTwo;
	//JList suggestionList;
	//ArgModelChecker amc1 = new ArgModelChecker();
	JSplitPane splitPane;
	int splitpane_inset_y = -200;
	JToolBar jtb1;
	GenerateText gentextObjectA,gentextObjectB;
	Theory t1;
	JPanel jp2;
	
    public JonaPad() {
    	super("JonaPad");
    	try
    	{
    		//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    	}
    	catch(Exception e)
    	{
    		System.out.println(e.getMessage());
    	}
    	getContentPane().setLayout(new BorderLayout());
    	JButton jb1;
    	
    	jtb1 = new JToolBar();
    	jb1 = new JButton(new ImageIcon("images/new.gif"));
    	jtb1.add(jb1);
       	jb1.setEnabled(false);
    	jb1 = new JButton(new ImageIcon("images/open.gif"));
    	jtb1.add(jb1);
       	jb1.setEnabled(false);
    	jb1 = new JButton(new ImageIcon("images/save.gif"));
    	jtb1.add(jb1);	
       	jb1.setEnabled(false);
    	JButton jbsupport = new JButton(new ImageIcon("images/supportersmall.gif"));
    	jtb1.add(jbsupport);
    	jbsupport.setEnabled(false);
    	jbsupport.setToolTipText("Add supporter to selected statement");
    	JButton jbattack = new JButton(new ImageIcon("images/attackersmall.gif"));
    	jtb1.add(jbattack);
    	jbattack.setEnabled(false);
    	jbattack.setToolTipText("Add attacker to selected statement");
    	JButton jbissue = new JButton(new ImageIcon("images/issue.gif"));
    	jtb1.add(jbissue);
    	jbissue.setEnabled(false);
    	jbissue.setToolTipText("Make issue");
      	JButton jbassumption = new JButton(new ImageIcon("images/assumption.gif"));
    	jtb1.add(jbassumption);
    	jbassumption.setEnabled(false);
    	jbassumption.setToolTipText("Make assumption");
    	
    	getContentPane().add(jtb1,BorderLayout.NORTH);
    	

    	int inset = 200;
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds(inset, inset,
                  screenSize.width  - inset*2,
                  screenSize.height - inset*2);
        
    	
        System.out.println("" + getHeight());
        
        jta1 = new JTextArea("jta1");
    	jta2 = new JTextArea("jta2");
    	jtp1 = new JTabbedPane();
    	jtp2 = new JTabbedPane();
    	jtp3 = new JTabbedPane();
    	jcb1 = new JComboBox();
    	//String[] test = {"test1","test2"};
    	//Knowledge.suggestionList = new JList();
    	
    	jp2 = new JPanel();
    	jp2.setLayout(new FlowLayout());
    	
    	jonta1 = new JonaTextArea();
    	jonta1.setPreferredSize(new Dimension(400,400));
    	
    	//jep1.setEditorKit(new HTMLEditorKit());
    	VisualJPanelOne = new VisualJPanel(jta1,jbsupport,jbattack,jbissue,jbassumption,1);
    	VisualJPanelOne.setSize(100,100);
    	
    	VisualJPanelTwo = new VisualJPanel(jta1,jbsupport,jbattack,jbissue,jbassumption,2);
    	VisualJPanelTwo.setSize(100,100);
    	
    	theoryPane = new JScrollPane(jta1);
    	problemsPane = new JScrollPane(jta2);
    	jsp3 = new JScrollPane(jonta1);
    	suggestionPane = new JScrollPane(Knowledge.suggestionList);
    	knowledgePane = new JScrollPane(Knowledge.knowledgeList);
    	
    	jsp3.setPreferredSize(new Dimension(100,100));
    	jcb1.setPreferredSize(new Dimension(100,20));
    	
    	jp2.add(new JLabel("Root statement"),BorderLayout.NORTH);
    	jp2.add(jcb1,BorderLayout.CENTER);
    	//jp1.add(jsp3,BorderLayout.CENTER);
    	//jp1.add(jp2,BorderLayout.WEST);
    	//jonta1.setPreferredSize(new Dimension(100,100));

    	jcb1.addItemListener(this);	
    //	jtp2.addTab("Theory",jsp1);
    	jtp2.addTab("Suggestions",suggestionPane);
    	jtp2.addTab("Knowledge",knowledgePane);
    	jtp3.addTab("Problems",problemsPane);
    	
    	addComponentListener(this);
    	
    	jtp3.setPreferredSize(new Dimension(200,100));
    	jtp1.setPreferredSize(new Dimension(150,300));
    	jtp2.setPreferredSize(new Dimension(200,100));

    	
    	//resizeComponents();
       	JSplitPane splitPane1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT ,
    			jtp2, jtp1);
    	splitPane1.setOneTouchExpandable(true);
    	splitPane1.setDividerLocation(150);
    	
    	splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
    			splitPane1, jtp3);
    	splitPane.setOneTouchExpandable(true);
    	splitPane.setDividerLocation(getHeight() + splitpane_inset_y);
    	
    	//Provide minimum sizes for the two components in the split pane
    	Dimension minimumSize = new Dimension(300, 50);
    	splitPane1.setMinimumSize(minimumSize);
    	jtp3.setMinimumSize(minimumSize);


    	//getContentPane().add(,BorderLayout.WEST);
    	getContentPane().add(splitPane);
    	//getContentPane().add(jtp1, BorderLayout.CENTER );
    	
    	modelTextField = new ModelJTextArea(jta1,jta2);
    	gentextA = new JTextArea(); 
    	gentextB = new JTextArea();    	
    	gentextPaneA = new JScrollPane(gentextA);
    	gentextPaneB = new JScrollPane(gentextB);
    	argModelField = new JScrollPane(modelTextField);
    	jtp1.addTab("Argumentation model",argModelField);
    	jtp1.addTab("Visualization",VisualJPanelOne);
    	jtp1.addTab("Visualization2",VisualJPanelTwo);
    	
    	//jp1.addComponentListener(this);
    	VisualJPanelOne.addComponentListener(this);
    	VisualJPanelTwo.addComponentListener(this);
    	argModelField.addComponentListener(this);
    	
        jfc1 = new JFileChooser();
        jfc1.setAcceptAllFileFilterUsed(false);
        jfc1.setFileFilter(new JonaFileFilter("dat"));
        //jfc1.setFileFilter(new JonaFileFilter("txt"));
  
        String rt="a: \"Double click to edit this issue\" as issue\n";
/*		String rt = "p=peter\nge=george\nwa=witness1\nwb=witness2\na: \"<p> shot <ge>\" as issue\n" +
		"b: \"According to <wa>, <p> shot <ge>\"  as assumption\n"+
		"c: \"According to <wb>, <p> dit not shoot <ge>\" as assumption\n"+
		"d: \"Witness testimonies are normally truthful\" as assumption\n"+
		"e: \"<wa> is unreliable\" as assumption\n"+
		"f: \"<wb> is unreliable\" as assumption\n"+		
		"g: if (b) then a as assumption\n" +
		"h: if (c) then !a as assumption\n" +
		"i: if (d) then g as assumption\n" +
		"j: if (d) then h as assumption\n" +
		"k: if (e) then !i as assumption\n" +
		"l: if (f) then !j as assumption\n" +
		"m: \"<wa> is betrouwbaar\" as assumption\n"+
		"n: if (m) then b as assumption\n";
	*/	
        /*
        String rt = "p=peter\nge=george\nwa=witness1\nwb=witness2\na: \"ISSUE\" as issue\n" +
		"b: \"SUPPORTER1\"  as assumption\n"+
		"c: \"ATTACKER1\" as assumption\n"+
		"d: \"ATTACKER2\" as assumption\n"+
        "e: \"SUPPORTER2\" as assumption\n" +
		"f: if (b) then a as assumption\n" +
		"g: if (e) then a as assumption\n" +
		"h: if (c) then !a as assumption\n" +
		"i: if (d) then !a as assumption\n";
		*/
		
		modelTextField.setText(rt);
		t1 = modelTextField.getActiveTheory();
		System.out.println(t1.toString());
		
        setJMenuBar(createMenuBar());
        
    	// Text Generation
    	jtp1.addTab("Generated Text (DF)", gentextPaneA );
    	gentextPaneA.addComponentListener(this);
    	gentextObjectA = new GenerateText(modelTextField.getActiveTheory());

    	jtp1.addTab("Generated Text (2)", gentextPaneB );
    	gentextPaneB.addComponentListener(this);
    	gentextObjectB = new GenerateText(modelTextField.getActiveTheory());
    	
    	
    	Knowledge.suggestionList.addMouseListener(this); 
    	Knowledge.knowledgeList.addMouseListener(this);
    	Knowledge.updateKnowledgeList();
    }
    public void itemStateChanged(ItemEvent e)
    {
    	System.out.println("Item state changed");
    	ArgObject s1 = (ArgObject)e.getItem();
    	Theory t1 = modelTextField.getActiveTheory();
    	if(t1 != null)
    	{
    		s1 = t1.makeTree(s1);
    		jonta1.visualize1(s1);
    	}
    	else
    	{
    		jonta1.setText("");
    	}
 
    	Knowledge.suggest(modelTextField.getText());
    }
    public void componentHidden(ComponentEvent e) 
    {	
    	System.out.println(e.getSource());
    	if(e.getSource() == modelTextField)
    	{
    		System.out.println("hidden textfield");

    	if(e.getSource() == VisualJPanelTwo)
    		VisualJPanelTwo.lostFocus();

    	    Theory tmp = modelTextField.getActiveTheory();
    	    if (tmp != null) t1 = tmp;
    	}   
    	if(e.getSource() == VisualJPanelTwo)
    	{
    		Theory tmp = VisualJPanelTwo.getVisualTheory();
    		if (tmp != null) t1 = tmp;
    		VisualJPanelTwo.lostFocus();

    	}
    	if(e.getSource() ==  VisualJPanelOne)
    	{
    		Theory tmp = VisualJPanelOne.getVisualTheory();
    		if (tmp != null) t1 = tmp;
    		VisualJPanelOne.lostFocus();
    	}
    }
    public void componentMoved(ComponentEvent e) {}
    public void componentResized(ComponentEvent e) 
    {
    	if(e.getSource() == this)
    	{
    		int toSet =  (int)(getHeight()*(450.0f / 624.0f)); 	
    		splitPane.setDividerLocation(getHeight() + splitpane_inset_y);	
    		
    	}
    }
    
    private void updateVisualization(VisualJPanel vjp)
    {
    	Theory t1 = modelTextField.getActiveTheory();
    	if(t1 != null)
    	{
    		vjp.setTheory(t1);
    	}
    }
    
    
    public void componentShown(ComponentEvent e) 
    {
    	System.out.println(t1.toString());
    	if(e.getSource() == argModelField)
    	{	
    	    modelTextField.setTheory(t1);
    		System.out.println("argModelField getoond");
    	}

    	if(e.getSource() == VisualJPanelTwo)
    		updateVisualization(VisualJPanelTwo);	

    	if(e.getSource() == VisualJPanelTwo)
    //		updateVisualization(vjpVisualJPanelTwo);
    		VisualJPanelTwo.setTheory(t1);
    	    

    	if(e.getSource() ==  VisualJPanelOne)
    		//updateVisualization(VisualJPanelOne)
    		VisualJPanelOne.setTheory(t1);
    	
    	else if (e.getSource() == gentextPaneA)
    	{
    		//Theory t1 = modelTextField.getActiveTheory();
        	if(t1 != null)
        	{
        		gentextObjectA.setTheory(t1,"A");
        		gentextA.setText(gentextObjectA.outputText());
        	}
    	}
    	else if (e.getSource() == gentextPaneB)
    	{
    		//Theory t1 = modelTextField.getActiveTheory();
        	if(t1 != null)
        	{
        		gentextObjectB.setTheory(t1,"B");
        		gentextB.setText(gentextObjectB.outputText());
        	}
    	}
    }
    
    
       
    //private void updateVisualization(VisualJPanel vjp)
   // {
    	//Theory t1 = modelTextField.getActiveTheory();
    //	if(t1 != null)
    	//{
    //		vjp.setTheory(t1);
    //	}
   // }
    
    
    private void updateComboBox()
    {
      	jcb1.removeAllItems();
    	Theory t1 = modelTextField.getActiveTheory();
    	if(t1 != null)
    	{
    		if(t1.getStatements() != null)
    		{
    			for(int i =0; i < t1.getStatements().length ; i++)
    			{
    				if(t1.getStatements()[i].getClass().getSimpleName().equals("Statement"))
    					jcb1.addItem(t1.getStatements()[i]);
    			}
    		}
    	}    	
    }
    
    protected JMenuBar createMenuBar() {
        JMenuBar menuBar = new JMenuBar();

        //Set up the lone menu.
       
        JMenu FileMenu = new JMenu("File");
        JMenu NewMenuInFileMenu = new JMenu("New");
        //File menu enable
        FileMenu.setEnabled(true);
        FileMenu.setMnemonic(KeyEvent.VK_F);
        menuBar.add(FileMenu);
        FileMenu.add(NewMenuInFileMenu);
        
        //Set up the first menu item.
        /*JMenuItem menuItem2 = new JMenuItem("Nothing");
        menuItem2.setActionCommand("Nothing");
        menuItem2.addActionListener(this);
        menuItem.
        menuItem.add(menu2);
        menuItem.add(menuItem2);*/
        JMenuItem NewArgumentationMenuItem = new JMenuItem("Argumentation model");
        NewArgumentationMenuItem.setMnemonic(KeyEvent.VK_N);
        NewArgumentationMenuItem.setAccelerator(KeyStroke.getKeyStroke(
               KeyEvent.VK_N, ActionEvent.ALT_MASK));
        NewArgumentationMenuItem.setActionCommand("new");
        NewArgumentationMenuItem.setEnabled(true);
        NewArgumentationMenuItem.addActionListener(this);
        NewMenuInFileMenu.add(NewArgumentationMenuItem);
       // menu2.add(menuItem2);
        JMenuItem menuItemInFileMenu = new JMenuItem("Open");
        menuItemInFileMenu.setMnemonic(KeyEvent.VK_O);
        menuItemInFileMenu.setAccelerator(KeyStroke.getKeyStroke(
                KeyEvent.VK_O, ActionEvent.ALT_MASK));
        menuItemInFileMenu.setActionCommand("open");
        menuItemInFileMenu.addActionListener(this);
        FileMenu.add(menuItemInFileMenu);
        
        menuItemInFileMenu = new JMenuItem("Save");
        menuItemInFileMenu.setMnemonic(KeyEvent.VK_S);
        menuItemInFileMenu.setAccelerator(KeyStroke.getKeyStroke(
                KeyEvent.VK_S, ActionEvent.ALT_MASK));
        menuItemInFileMenu.setActionCommand("save");
        menuItemInFileMenu.addActionListener(this);
        FileMenu.add(menuItemInFileMenu); 
        
        //Set up the second menu item.
        menuItemInFileMenu = new JMenuItem("Quit");
        menuItemInFileMenu.setMnemonic(KeyEvent.VK_Q);
        menuItemInFileMenu.setAccelerator(KeyStroke.getKeyStroke(
                KeyEvent.VK_Q, ActionEvent.ALT_MASK));
        menuItemInFileMenu.setActionCommand("quit");
        menuItemInFileMenu.addActionListener(this);
        FileMenu.add(menuItemInFileMenu);


        // Knowledge
        JMenu knowledgeMenu = new JMenu("Knowledge");
        menuBar.add(knowledgeMenu);
        String key = "Edit Knowledge";
        JMenuItem menuItemInKnowledgeMenu = new JMenuItem(key);
        menuItemInKnowledgeMenu.setActionCommand(key);
        menuItemInKnowledgeMenu.addActionListener(this);
        knowledgeMenu.add(menuItemInKnowledgeMenu);
        
        for (Enumeration e = Knowledge.getKnowledge() ; e.hasMoreElements() ;) {
            key = (String) e.nextElement();
        	//System.out.println(key);
            menuItemInKnowledgeMenu = new JMenuItem(key);
            menuItemInKnowledgeMenu.setActionCommand(key);
            menuItemInKnowledgeMenu.addActionListener(this);
            knowledgeMenu.add(menuItemInKnowledgeMenu);
        }
        
        return menuBar;
    }

   
    //React to menu selections.
    public void actionPerformed(ActionEvent e) {
    	if(e.getActionCommand().equals("new")){
    		//System.out.println("New Argumentation Model must be made here!");
    		//newArgumentationModel();    	
    		//modelTextField.setText("");
    		modelTextField.setText("a: \"Make your own issue \" as issue\n");
    		
    	}
    	else if(e.getActionCommand().equals("save"))
    		saveFile();
    	else if(e.getActionCommand().equals("open"))
    		openFile();
    	else if(e.getActionCommand().equals("quit"))
    		this.quit();
    	else if(e.getActionCommand().equals("Edit Knowledge"))
    		KnowledgeEditor.createAndShowGUI();
    	
    	else
    	{
    		String knowledge;
    		if (null !=(knowledge = Knowledge.getKnowledge(e.getActionCommand())))
    			modelTextField.setText(modelTextField.getText()+"\n"+knowledge);
    	}
    }
    
    private void saveFile()
    {
    	Theory t1 = null;
    	t1 =modelTextField.getActiveTheory();
    	if(t1 != null)
    	{
    		jfc1.showSaveDialog(this);
    		File f1 = jfc1.getSelectedFile();
    		String path = f1.getAbsolutePath() + ".dat";
    		try
    		{
    			saveAsXML(t1,path);
    		}
    		catch(IOException e)
    		{
    			jta2.setText("Error:\n" + e.getMessage() );
    		}
    	}
    	else
    	{
    		jta2.setText("Cannot save because of errors in model");
    	}
    }
	
    private void openFile()
    {
    	Theory t1 = null;
    	boolean error = false;
 		jfc1.showOpenDialog(this);
		File f1 = jfc1.getSelectedFile();
		if(f1 != null)
		{
			String path = f1.getAbsolutePath();
    		try
    		{
    			t1 = loadFromXML(path);
    		}
    		catch(IOException e)
    		{
    			error = true;
    			jta2.setText("Error:\n" + e.getMessage() );
    		}
			if(!error)
			{		
				jta1.setText(t1.toString());
				modelTextField.setTheory(t1);
				updateComboBox();
				
			}
		}
		else
		{
			jta2.setText("No file specified");
		}
    }
    
    
    public Theory loadFromXML(String fileName) throws IOException
	{
		String input ="";
		FileReader fr1 = new FileReader(fileName);
		BufferedReader br = new BufferedReader(fr1); 
		String record ="";
		while ((record=br.readLine()) != null ) 
		{  
			  input+=record;
		}  
		return(Theory)xstream.fromXML(input);
		//return null;
	}
	
    public void saveAsXML(Theory t1,String fileName) throws IOException
	{
    	String output="xml-spul verwijderd";
		FileWriter fw1 = new FileWriter(fileName);
		fw1.write(output);
		fw1.flush();
		fw1.close();
	}
    
//	The mouselistener.
	public void mouseClicked(MouseEvent e) {
	        if (e.getClickCount() == 2) {
	            //int index = Knowledge.suggestionList.locationToIndex(e.getPoint());
	            modelTextField.setText(modelTextField.getText()+"\n"+Knowledge.getKnowledge((String) ((JList)e.getSource()).getSelectedValue()));
	         }
	    }
	
	public void mousePressed(MouseEvent e) {};
	
	public void mouseReleased(MouseEvent e) {};
	
	public void mouseEntered(MouseEvent e) {};
	
	public void mouseExited(MouseEvent e) {};
	
    
   

    //Quit the application.
  
    protected void quit() {
        System.exit(-1);
    }
    
    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
   	public static void createAndShowGUI() {
        //Make sure we have nice window decorations.
        //JFrame.setDefaultLookAndFeelDecorated(false);
   		
        //Create and set up the window.
        JonaPad frame = new JonaPad();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Display the window.
        frame.setVisible(true);
    }

}